import { _decorator, Camera, Component, EventTouch, find, Node, UITransform, Vec3, Size, Vec2, Canvas, EventKeyboard, KeyCode, input, Input, View, size, BoxCollider, Widget, UIOpacity, sys, game, Game } from 'cc';
import { UnitPlanet } from '../Entity/UnitPlanet';
import { Global, GuideTipData } from '../Util/Global';
import GameEventMgr, { GameEvent } from '../Model/GameEventMgr';
import { UICtrl } from './UICtrl';
import { EconomicCom } from '../Entity/Component/EconomicCom';
import { Unit } from '../Entity/Unit';
import { PlayCtrlUI } from '../UI/Component/PlayCtrlUI';
import { GameOverDialog } from '../UI/Dialog/GameOverDialog';
const { ccclass, property } = _decorator;

/**
 * 玩家操作控制器、同时刷新控制镜头
 */
@ccclass('PlayerCtrl')
export class PlayerCtrl extends Component {

    @property
    cameraFollowOffset: number = 300;
    /**玩家操控单位 */
    // @property(UnitPlanet)
    private _targetUnit: UnitPlanet = null;
    get playerUnit() {
        return this._targetUnit;
    }
    set playerUnit(value: UnitPlanet) {
        this._targetUnit = value;
    }

    @property(Node)
    public playerMoveView: Node = null;
    @property(Node)
    public miniPlayCtrlUI: Node = null;
    @property(PlayCtrlUI)
    public playCtrlUI: PlayCtrlUI = null;

    public viewCamera: Camera = null;
    public uiCamera: Camera = null;

    private _allowCtrl: boolean = false;
    get allowCtrl(): boolean {
        return this._allowCtrl;
    }

    set allowCtrl(value: boolean) {
        if (this._allowCtrl != value) {
            if (value) {
                this.gameUIView = true;
                //鼠标滚轮
                // this.node.on(Node.EventType.MOUSE_WHEEL, this.onMouseWheel, this);
            }
            else {
                this.gameUIView = false;
                this._moveDir.set(0, 0);
                // 监听触摸事件
                // this.node.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
                // this.node.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
                // this.node.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
                //鼠标滚轮
                // this.node.off(Node.EventType.MOUSE_WHEEL, this.onMouseWheel, this);
            }
        }
        this.playCtrlUI.node.active = value && Global.UsingFixedJoystick;
        this.playCtrlUI.maskBgNode.active = value && Global.UsingFixedJoystick;
        this._allowCtrl = value;
    }

    private _gameUIOpacity: UIOpacity = null;
    set gameUIView(value: boolean) {
        //由于ui涉及到缩放，如果场景中默认是不激活的状态，当canvas缩放后再激活那么对齐会出错
        //最好是场景中默认激活，在start中再关闭，这里直接用透明度代替了
        if (this._gameUIOpacity == null) {
            this._gameUIOpacity = find("UICanvas/GameUI").getComponent(UIOpacity);
        }
        this._gameUIOpacity.opacity = value ? 255 : 0;
    }

    start() {

        this.playCtrlUI.onTouchActionCallback = this.onMobilePlayCtrlUIAction.bind(this);

        let camera = find("ViewCanvas/Camera");
        if (camera) {
            this.viewCamera = camera.getComponent(Camera);
        }
        camera = find("UICanvas/Camera");
        if (camera) {
            this.uiCamera = camera.getComponent(Camera);
        }

        // console.log(this.unit)
        this.gameUIView = false;
        // 监听触摸事件
        this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        //鼠标滚轮
        this.node.on(Node.EventType.MOUSE_WHEEL, this.onMouseWheel, this);
        // this.unit.playerCtrl = true;
        // let economic = this.unit.getComponent(EconomicCom);
        // economic && economic.AddPowerConsumer(this.unit);

        Global.CameraOrthoHeight = this.viewCamera.orthoHeight;

        // this._moveDir = this.node.position;

        GameEventMgr.Register(this, GameEvent.PlayerDestroy, this.PlayerDestroyEventHandler.bind(this));

        // 在节点启用时添加键盘事件监听器
        input.on(Input.EventType.KEY_DOWN, this.onKeyPressing, this);
        input.on(Input.EventType.KEY_PRESSING, this.onKeyPressing, this);
        input.on(Input.EventType.KEY_UP, this.onKeyUp, this);
    }

    updateWidget(node: Node) {
        for (let i = 0; i < node.children.length; i++) {
            let child = node.children[i];
            let widget = child.getComponent(Widget);
            if (widget) {
                widget.alignMode = 0;
                widget.updateAlignment();
            }
            this.updateWidget(child);
        }
    }

    private _keyDir = new Vec3;
    onKeyUp(event: EventKeyboard) {
        if (event.keyCode === KeyCode.KEY_W) {
            this._keyDir.y = 0;
        }
        else if (event.keyCode === KeyCode.KEY_S) {
            this._keyDir.y = 0;
        }
        else if (event.keyCode === KeyCode.KEY_A) {
            this._keyDir.x = 0;
        }
        else if (event.keyCode === KeyCode.KEY_D) {
            this._keyDir.x = 0;
        }
        if (this._keyDir.x == 0 && this._keyDir.y == 0) {
            this._hold = false;
            this.onPlayerCtrlCancel();
        }
        // else {
        //     if (this._allowCtrl && this.playerUnit && !this.playerUnit.death) {

        //         this.onCtrlMoveAction(this._keyDir);
        //     }
        // }
        // console.log("按了", this._keyDir)
    }

    onKeyPressing(event: EventKeyboard) {
        this._hold = true;
        let num = 1000;
        if (event.keyCode === KeyCode.KEY_W) {
            this._keyDir.y = num;
        }
        else if (event.keyCode === KeyCode.KEY_S) {
            this._keyDir.y = -num;
        }
        else if (event.keyCode === KeyCode.KEY_A) {
            this._keyDir.x = -num;
        }
        else if (event.keyCode === KeyCode.KEY_D) {
            this._keyDir.x = num;
        }

        // console.log("按了", this._keyDir)
        // if (this._allowCtrl && this.playerUnit && !this.playerUnit.death) {

        //     this.onCtrlMoveAction(this._keyDir);
        // }
    }

    private PlayerDestroyEventHandler(player: Unit) {
        this.playerMoveDir.set(0, 0);
        this.playCtrlUI.node.active = false;
        this.playCtrlUI.maskBgNode.active = false;
    }

    /**检测相机是否出边界，并将其限制在边界内 */
    private checkCameraMoveOutBoundary(prePos?: Vec3) {
        let center = Global.gameManager.mapCtrl.node.getWorldPosition();
        let size = Global.gameManager.mapCtrl.collider.size;

        let targetPos = (prePos && prePos.clone()) || this.viewCamera.node.parent.getWorldPosition();
        // let targetSize = this.camera.node.parent.getComponent(UITransform).contentSize.clone();
        let targetSize = this.node.getComponent(UITransform).contentSize.clone();
        // targetSize.width *= Global.CameraOrthoScale;//contentSize好像本身不收scale影响
        // targetSize.height *= Global.CameraOrthoScale;

        if (targetPos.x < center.x) {
            targetPos.x = targetPos.x - targetSize.width / 2;
        }
        else {
            targetPos.x = targetPos.x + targetSize.width / 2;
        }

        if (targetPos.y < center.y) {
            targetPos.y = targetPos.y - targetSize.height / 2;
        }
        else {
            targetPos.y = targetPos.y + targetSize.height / 2;
        }

        let inX = false;
        if (targetPos.x <= center.x + size.width / 2) {
            if (targetPos.x >= center.x - size.width / 2) {
                inX = true;
            }
            else if (prePos) {
                prePos.x = center.x - size.width / 2 + targetSize.width / 2;
            }
        }
        else if (prePos) {
            prePos.x = center.x + size.width / 2 - targetSize.width / 2;
        }

        let inY = false;
        if (targetPos.y <= center.y + size.height / 2) {
            if (targetPos.y >= center.y - size.height / 2) {
                inY = false;
            }
            else if (prePos) {
                prePos.y = center.y - size.height / 2 + targetSize.height / 2;
            }
        }
        else if (prePos) {
            prePos.y = center.y + size.height / 2 - targetSize.height / 2;
        }

        return !inX && !inY;
    }

    private _cameraPos: Vec3 = new Vec3();
    private _moveDir: Vec3 = new Vec3();

    public playerMoveDir: Vec2 = new Vec2();

    protected update(dt: number): void {
        // if (this.unit == null || this.unit.death) {
        //     return;
        // }

        this.updatePlayerMoveDirectIcon();
        this.updateCameraPos();

        if (this._hold) {
            this.onTouchHold();

        }
        else {
            // this.unit.Stand(dt);
        }

    }

    updatePlayerMoveDirectIcon() {
        //刷新控制力显示图标
        if (this.playerMoveView && this.allowCtrl) {
            if (this.playerMoveDir.length() > 0 && this.playerUnit && !this.playerUnit.death) {
                let nor = this.playerMoveDir.normalize();
                let pos = this.playerUnit.unitWorldPos
                // this.viewCamera.worldToScreen(pos, pos);
                this.viewCamera.convertToUINode(pos, Global.gameManager.gameUI, pos);
                pos.x += nor.x * 100;
                pos.y += nor.y * 100;
                this.playerMoveView.setPosition(pos);

                this.playerMoveView.active = true;
                let angle = nor.signAngle(Vec2.UNIT_Y) * 180 / Math.PI;
                this.playerMoveView.setRotationFromEuler(0, 0, -angle);
            }
            else {
                this.playerMoveView.active = false;
            }
        }
    }

    updateCameraPos() {
        if (this.viewCamera) {//更新相机位置
            let dir = this._moveDir;
            if (!Global.gameManager.pause && this.playerUnit && !this.playerUnit.death) {
                let unitPos = this.playerUnit.unitWorldPos;
                // let moveDir = this._moveToPos.clone().subtract(this.playerUnit.unitWorldPos).normalize();
                // if(this._hold){//做一个目标方向上的偏移
                //     unitPos.add(moveDir.multiplyScalar(this.cameraFollowOffset));
                // }
                if (this.playerUnit.speed > 3) {
                    let unitV = this.playerUnit.ToVec3(this.playerUnit.rigBody.linearVelocity);
                    //做一个移动方向上的偏移 速度越大偏移越小
                    let _offset = this.cameraFollowOffset / this.playerUnit.speed;
                    let _add_v = unitV.multiplyScalar(_offset);
                    if (unitV.length() > 1000) {
                        unitV.normalize().multiplyScalar(1000);
                    }
                    // console.log(unitV.length(), _offset);
                    unitPos.add(_add_v);
                }
                dir = unitPos.subtract(this._cameraPos);
            }
            this.viewCamera.node.parent.getWorldPosition(this._cameraPos);
            this._cameraPos.z = 0;

            // let cameraDir = unitPos.subtract(this._cameraPos);
            let cameraDir = dir;

            if (!this.playerUnit || this.playerUnit.death) {//无目标
                cameraDir.y = cameraDir.y * Global.screenAspectRatio;
            }

            let le = cameraDir.length();
            if (le > 10) {

                le = Math.min(1, le / 10000);
                let moveDir = cameraDir.multiplyScalar(le);
                let movePos = this._cameraPos.clone().add(moveDir);
                this.checkCameraMoveOutBoundary(movePos);
                this.viewCamera.node.setPosition(0, 0, 0);//横竖屏切换后会出现相机错位！？
                this.viewCamera.node.parent.setWorldPosition(movePos);
            }
        }
    }

    protected lateUpdate(dt) {
        if (this.viewCamera.orthoHeight != Global.CameraOrthoHeight) {
            // let vec = new Vec3(1, 1, 1);
            // vec.x = Global.CameraOrthoHeight / Global.designScreenSize.height * 2;
            // vec.y = Global.CameraOrthoHeight / Global.designScreenSize.height * 2;
            // this.node.scale = vec;
            this.viewCamera.orthoHeight = Global.CameraOrthoHeight;
            let transform = this.node.getComponent(UITransform);
            let targetSize = new Size();
            targetSize.width = 1280 * Global.CameraOrthoScale;//contentSize好像本身不收scale影响
            targetSize.height = 720 * Global.CameraOrthoScale;
            transform.contentSize = targetSize;

            if (Global.CameraOrthoScale == 2) {
                this._CameraOrthoScaleUsed = true
            }
        }
    }

    private _hold: boolean = false;
    private _fristTouchPos: Vec3 = new Vec3;
    private _moveTouchPos: Vec3 = new Vec3;
    private _lastFrameDistance: number = 0;

    private _CameraOrthoScaleUsed: boolean = false;
    onTouchStart(touchEvent: EventTouch) {
        if (touchEvent.getTouches().length >= 2) {
            //第一次触摸时，不会大于二，要在移动中判断
        }
        else if (touchEvent.getTouches().length == 1) {
            //获取触摸坐标
            let touch = touchEvent.getLocation();

            this._fristTouchPos = new Vec3(touch.x, touch.y, 0);
            // let worldPos = this.camera.screenToWorld(this._fristTouchPos);
            // this._moveToPos.x = worldPos.x;
            // this._moveToPos.y = worldPos.y;

            this._hold = true;

            let worldPos = this.uiCamera.screenToWorld(this._fristTouchPos);
            let localPos = this.uiCamera.convertToUINode(worldPos, this.miniPlayCtrlUI.parent);
            this.miniPlayCtrlUI.setPosition(localPos);

            //没有缩放过视角，就随机提示
            if (this._allowCtrl && !this._CameraOrthoScaleUsed &&
                Math.ceil(Global.gameManager.time) % 10 == 0) {
                GameEventMgr.Dispatch(GameEvent.TipGameMessage, "MOSS：长官！双指缩放可以放大缩小视角。", 5);
            }
        }

    }

    onTouchEnd(touchEvent: EventTouch) {
        this._hold = false;
        this._lastFrameDistance = 0;
        this._moveTouchPos.set(0, 0, 0);
        this._fristTouchPos.set(0, 0, 0);
        this.miniPlayCtrlUI.active = false;

        if (this._allowCtrl) {
            this.onPlayerCtrlCancel();
        }

        this.lateUpdateScale();
    }

    lateUpdateScale(time: number = 0) {

        this.scheduleOnce(() => {

            let vec = new Vec3(1, 1, 1);
            vec.x = Global.CameraOrthoHeight / Global.designScreenSize.height * 2;
            vec.y = Global.CameraOrthoHeight / Global.designScreenSize.height * 2;
            this.node.scale = vec;//canvas在手机上频繁缩放会导致黑屏(可能因为z=0)，不知道原因，所以就每次缩放完再同步了
            // if (this._allowCtrl) this.gameUIView = true;
        }, time)
    }

    onTouchMove(touchEvent: EventTouch) {

        // 获取触摸坐标
        if (touchEvent.getTouches().length >= 2) {
            return;
            let touch1 = touchEvent.getTouches()[0];
            let touch2 = touchEvent.getTouches()[1];
            let currentDistance = touch1.getLocation().subtract(touch2.getLocation()).length();

            let changeScale = (this._lastFrameDistance - currentDistance) / 300;

            changeScale = 1 + changeScale;
            if (this._lastFrameDistance == 0) {
                changeScale = 1;
            }

            this._lastFrameDistance = currentDistance;

            // console.log("移动变化==>" + changeScale);

            let orthoH = Global.CameraOrthoHeight;

            orthoH *= changeScale;//缩放

            orthoH = orthoH > Global.designScreenSize.height ?
                Global.designScreenSize.height : orthoH;
            orthoH = orthoH < Global.designScreenSize.height / 2 ?
                Global.designScreenSize.height / 2 : orthoH;
            Global.CameraOrthoHeight = orthoH;

            // this.gameUIView = false;
        }
        else {

            let touch = touchEvent.getLocation();
            this._moveTouchPos.set(touch.x, touch.y, 0);

            if (!Global.UsingFixedJoystick && this._allowCtrl && this.playerUnit && !this.playerUnit.death) {
                let success = this.onPlayerCtrlMoving();
                if (!success) {
                    GameEventMgr.Dispatch(GameEvent.LogGameMessage, "燃料耗尽！！！");
                    UICtrl.showDialog(GameOverDialog).setData({ overType: 1 })
                    this._hold = false;
                }
            }

            if (!Global.UsingFixedJoystick || !this.playerUnit || this.playerUnit.death) {
                let lp = this._moveDir.clone();
                if (lp.length() > 50) {
                    lp = lp.normalize().multiplyScalar(50);
                }
                // 更新 ctrlNode 位置
                this.miniPlayCtrlUI.getChildByName('CtrlIcon').setPosition(lp);
                this.miniPlayCtrlUI.active = true;
            }
        }
    }

    onTouchHold() {
        if (this._moveTouchPos.length() == 0 && this._keyDir.length() == 0) {
            return;
        }

        if (!Global.UsingFixedJoystick && this._allowCtrl && this.playerUnit && !this.playerUnit.death) {

            let f_worldPos = this.viewCamera.screenToWorld(this._fristTouchPos);
            let worldPos = this.viewCamera.screenToWorld(this._moveTouchPos);
            let dir = worldPos.subtract(f_worldPos);

            if (this._keyDir.length() > 0) {
                this.onCtrlMoveAction(this._keyDir);
            }
            else {
                this.onCtrlMoveAction(dir);
            }
        }
        else {
            let f_worldPos = this.viewCamera.screenToWorld(this._fristTouchPos);
            let worldPos = this.viewCamera.screenToWorld(this._moveTouchPos);
            let dir = worldPos.subtract(f_worldPos);
            this._moveDir.x = dir.x;
            this._moveDir.y = dir.y;
        }
    }

    onMouseWheel(event) {
        // 获取滚轮的滚动数据
        let delta = event.getScrollY();
        let orthoH = Global.CameraOrthoHeight;

        orthoH += -delta / 50;

        orthoH = orthoH > Global.designScreenSize.height ?
            Global.designScreenSize.height : orthoH;
        orthoH = orthoH < Global.designScreenSize.height / 2 ?
            Global.designScreenSize.height / 2 : orthoH;

        let vec = new Vec3(1, 1, 1);
        vec.x = orthoH / Global.designScreenSize.height * 2;
        vec.y = orthoH / Global.designScreenSize.height * 2;
        this.node.scale = vec;

        Global.CameraOrthoHeight = orthoH;
    }

    onPlayerCtrlMoving(): boolean {

        let economic = this.playerUnit.getComponent(EconomicCom);
        if (economic) {
            //点击时消耗
            economic.AddPowerConsumer(this.playerUnit);
            if (economic.mine_res > 0) {//燃料充足
                if (this.playerUnit && !this.playerUnit.death) {
                    this.playerMoveDir = this.playerUnit.MoveToWeightDt_byDir(this._moveDir);
                }
            }
            else {
                return false
            }
        }
        else {
            this.playerMoveDir = this.playerUnit.MoveToWeightDt_byDir(this._moveDir);
        }

        return true
    }

    onPlayerCtrlCancel() {
        if (this.playerUnit && !this.playerUnit.death) {
            this.playerMoveDir.set(0, 0);
            let economic = this.playerUnit.getComponent(EconomicCom);
            //不点击时取消
            economic && economic.RemovePowerConsumer(this.playerUnit);
        }
    }

    onMobilePlayCtrlUIAction(tag: string) {
        if (this._allowCtrl && this.playerUnit && !this.playerUnit.death) {

            if (tag == 'hold') {
                this.onCtrlMoveAction(this.playCtrlUI.ctrlDirect);
            }
            else if (tag == 'end') {
                this._hold = false;
                this.onPlayerCtrlCancel();
            }
        }
    }

    onCtrlMoveAction(dir: Vec3) {
        this._hold = true;
        // let directPos = this.playerUnit.unitWorldPos.add(dir);
        // console.log(dir)
        this._moveDir.x = dir.x;
        this._moveDir.y = dir.y;
        let success = this.onPlayerCtrlMoving();
        if (!success) {
            GameEventMgr.Dispatch(GameEvent.LogGameMessage, "燃料耗尽！！！");
            UICtrl.showDialog(GameOverDialog).setData({ overType: 1 })
            this._hold = false;
        }
    }
}


